package xyz.scootaloo.kami.server.service

import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible

/**
 * @author flutterdash@qq.com
 * @since 2022/1/17 21:43
 */

fun reflect(obj: Any): ReflectWrapper = ReflectWrapper(obj)

class ReflectWrapper(private val obj: Any) {
    private val klass = obj::class

    @Suppress("UNCHECKED_CAST")
    fun <T> field(name: String): T {
        val mp = klass.memberProperties.firstOrNull { it.name == name }!!
        mp.isAccessible = true
        return mp.call(obj) as T
    }

    fun call(name: String, vararg args: Any?): Any? {
        val mf = klass.memberFunctions.firstOrNull { it.name == name }!!
        mf.isAccessible = true
        return mf.call(args)
    }

    fun <T> field(name: String, def: T): T = try {
        field(name)
    } catch (e: Throwable) {
        def
    }
}